﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NAnt.Core;
using NAnt.Core.Attributes;
using System.Diagnostics;

namespace NAntExt.Tasks
{
    /// <summary>
    /// The base class for all the tasks which use the schtasks.exe.
    /// </summary>
    public abstract class ProcessTaskBase : Task
    {
        /// <summary>
        /// Gets the identifying information for a process.
        /// </summary>
        /// <param name="process">The process.</param>
        /// <returns>Returns the identifying information for a process.</returns>
        protected static string GetProcessInfo(Process process)
        {
            if (process == null)
                return string.Empty;

            var sb = new System.Text.StringBuilder();

            sb.AppendFormat("ProcessName: '{0}'", process.ProcessName);

            if (!string.IsNullOrEmpty(process.MachineName) && process.MachineName != ".")
                sb.AppendFormat(" MachineName: '{0}'", process.MachineName);

            if (!string.IsNullOrEmpty(process.StartInfo.UserName))
                sb.AppendFormat(" UserName: '{0}'", process.StartInfo.UserName);

            return sb.ToString();
        }
        
        [TaskAttribute("machineName")]
        [StringValidator(AllowEmpty = true)]
        public string MachineName { get; set; }

        [TaskAttribute("processName")]
        [StringValidator(AllowEmpty = true)]
        public string ProcessName { get; set; }

        [TaskAttribute("userName")]
        [StringValidator(AllowEmpty = true)]
        public string UserName { get; set; }

        /// <summary>
        /// Gets the process who match our criteria to wait on.
        /// </summary>
        /// <returns>Returns the processes who match our criteria.</returns>
        protected List<Process> GetProcesses()
        {
            List<Process> processes;
            if (string.IsNullOrEmpty(ProcessName))
            {
                if (string.IsNullOrEmpty(MachineName))
                    processes = new List<Process>(Process.GetProcesses());
                else
                    processes = new List<Process>(Process.GetProcesses(MachineName));
            }
            else
            {
                if (string.IsNullOrEmpty(MachineName))
                    processes = new List<Process>(Process.GetProcessesByName(ProcessName));
                else
                    processes = new List<Process>(Process.GetProcessesByName(ProcessName, MachineName));
            }
            
            if (string.IsNullOrEmpty(UserName))
                return processes;
            else
                // if UserName was provided then filter the processes by the username
                return processes.FindAll(p => string.Equals(p.StartInfo.UserName, UserName, StringComparison.InvariantCultureIgnoreCase));
        }

        /// <summary>
        /// Gets all the input info into one string to log it.
        /// </summary>
        /// <returns>Returns a string with all the input info concatinated together.</returns>
        protected virtual string GetInputInfo()
        {
            var sb = new System.Text.StringBuilder();

            if (!string.IsNullOrEmpty(ProcessName))
                sb.AppendFormat("processName: {0}", ProcessName);

            if (!string.IsNullOrEmpty(MachineName))
            {
                if (sb.Length > 0)
                    sb.Append(" ");
                sb.AppendFormat("machineName: {0}", MachineName);
            }

            if (!string.IsNullOrEmpty(UserName))
            {
                if (sb.Length > 0)
                    sb.Append(" ");

                sb.AppendFormat("userName: {0}", UserName);
            }

            return sb.ToString();
        }

    }
}
